home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 9
/
FM Towns Free Software Collection 9.iso
/
t_os
/
tool
/
extdrv
/
src
/
buf_rdir.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-16
|
4KB
|
170 lines
#include "extdrv.h"
#include "file.h"
#include "dir.h"
#include "buffer.h"
#include "dos.h"
#include "extern.h"
int n_rootdir;
struct rdirbuf far *root_base = NULL, far *root_dir = NULL;
struct rdirbuf far *root_tail = NULL;
struct rdirbuf far *get_root(struct drvinfo far *d, u_int entry)
{
u_short off, sector;
struct rdirbuf far *p, far *free;
off = entry / N_RDIR_ENTRY;
free = NULL;
for (p = root_dir; p != NULL; p = p->next){
if (p->drv == d && p->off == off){
if (p != root_dir){
if ((p->prev->next = p->next) == NULL)
root_tail = p->prev;
else
p->next->prev = p->prev;
p->next = root_dir;
p->prev = NULL;
root_dir->prev = p;
root_dir = p;
}
return (p);
}
if (p->drv == NULL)
free = p;
}
if (free == NULL){
p = root_tail;
if (p->pp != NULL){
p->pp->drv = NULL; /* invalidate */
p->pp = NULL;
}
if (p->dirty){
d = p->drv;
sector = RDIRBUFSIZ / d->sectsiz;
sector = d->rdir_off + p->off * sector;
if (write2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, p->buf) != 0){
#ifdef DEBUG
auxputs("write error ");
#endif
return (NULL);
}
p->dirty = FALSE;
}
root_tail = p->prev;
p->prev->next = NULL;
root_dir->prev = p;
p->next = root_dir;
p->prev = NULL;
root_dir = p;
} else {
if ((p = free) != root_dir){
if (p->next == NULL)
root_tail = p->prev;
else
p->next->prev = p->prev;
p->prev->next = p->next;
root_dir->prev = p;
p->next = root_dir;
p->prev = NULL;
root_dir = p;
}
}
p->drv = d;
p->off = off;
if (off == d->rdir_last_sec)
p->n_entry = d->rdir_last_size;
else
p->n_entry = N_RDIR_ENTRY;
sector = RDIRBUFSIZ / d->sectsiz;
sector = d->rdir_off + off * sector;
if (read2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, p->buf) != 0){
#ifdef DEBUG
auxputs("read error ");
#endif
p->drv = NULL;
return (NULL);
}
#ifdef DEBUG_BUF
auxputs("RBUF#");
auxprinthex((u_long)((char far *)p - (char far *)root_base)/sizeof (struct rdirbuf));
auxputs(" DISK-READ,");
auxprinthex(sector);
auxputs(",");
auxprinthex(p->n_entry);
auxputs(" ");
#endif
return (p);
}
flush_root(struct drvinfo far *d, int invalidate)
{
struct rdirbuf far *p;
u_short sector;
#ifdef DEBUG
auxputs("flush_root ");
#endif
for (p = root_dir; p != NULL; p = p->next){
if ((d == NULL && p->drv != NULL) || p->drv == d){
if (p->dirty){
d = p->drv;
sector = RDIRBUFSIZ / d->sectsiz;
sector = d->rdir_off + p->off * sector;
if (write2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize,
p->buf) != 0){
#ifdef DEBUG
auxputs("write error ");
#endif
return (-1);
}
p->dirty = FALSE;
}
if (invalidate){
if (p->pp != NULL){
p->pp->drv = NULL; /* invalidate */
p->pp = NULL;
}
p->drv = NULL;
}
}
}
return (0);
}
inv_root(u_int devno)
{
struct rdirbuf far *p;
for (p = root_dir; p != NULL; p = p->next){
if (p->drv != NULL && p->drv->devno == devno){
if (p->pp != NULL){
p->pp->drv = NULL;
p->pp = NULL;
}
p->drv = NULL;
p->dirty = FALSE;
}
}
return (0);
}
struct rdirbuf far *root_read(struct drvinfo far *d, int entry)
{
struct rdirbuf far *p;
if (entry >= d->n_rdir)
return (NULL);
if ((p = get_root(d, entry)) == NULL){
return (NULL);
}
#ifdef DEBUG_BUF
auxputs("RBUF#");
auxprinthex((u_long)((char far *)p - (char far *)root_base)/sizeof (struct rdirbuf));
auxputs(" ");
auxputs("\r\n");
#endif
return (p);
}